/* 运行开发环境 */
const { spawn } = require('child_process')
const ora = require('ora')
const chalk = require('chalk')

const envType = {
  message: '请选择需要运行的项目: ', // 提示文字
  cli: 'vue-cli-service serve', // 运行指令
}

module.exports = async function() {

  /* 获取入口配置 */
  const entries = await require('../utils/selectEntry')(envType.message)

  let finishLen = 0

  const compileRes = {}

  // 开始加载动画
  const spinner = ora('正在编译...')

  spinner.start()

  entries.forEach(item => {
    compileRes[ item.entry ] = {
      name: item.name,
      log: []
    }

    /* 入口参数写入 */
    require('../utils/envWrite')(item)

    const ls = spawn(envType.cli, [], { shell: true })

    ls.stdout.on('data', (data) => {
      logStdout(data, item)
    })

    /* 非主动数据流，包含了编译进度 */
    ls.stderr.on('data', (data) => {
      logProgress(data)
    })

    ls.on('close', (code) => {
      compileEnd(item.entry, `编译运行失败: ${ chalk.red.bold(item.name) }`)
      console.log(`child process exited with code ${ code }`)
    })
  })

  /**
   * 打印编译进度
   */
  function logProgress(data) {
    data = data.toString()
    /* 编译阶段，查找n%数字，进行输出 */
    const reg = /([0-9]{1,2}|100)%/

    if (reg.test(data)) {
      spinner.text = `编译中: ${ data.match(reg)[ 0 ] }`
    } else if (/error/gi.test(data)) { // 报错信息
      console.log(data)
    } else {
      console.log(data)
    }
  }

  /**
   * 打印输出流
   * @param {String} data 终端打印的数据
   * @param {Object} 入口
   */
  function logStdout(data, item) {
    data = data.toString()
    let reg = /(local|network).*\n/gi

    /* 只打印Local和network */
    if (reg.test(data)) {
      data.match(reg).forEach(str => {
        str = str.trim()

        /* 路径高亮 */
        reg = /(http|https|localhost).*/gi

        /* 是否有开发路径出现,有的话说明编译成功 */
        if (reg.test(str)) {
          const path = str.match(reg)[ 0 ]

          str = str.replace(path, chalk.blue.bold(path))
          compileRes[ item.entry ].log.push(str)
        }
      })
    } else if (/param/.test(data)) { // 自定义参数
      console.log(data)
    } else if (/Note that the development build is not optimized/ig.test(data)) { // 编译完成
      compileEnd(item.entry, `编译运行成功: ${ chalk.green.bold(item.name) }`)
    } else if (finishLen === entries.length && /Compiled successfully/ig.test(data)) {
      saveLog(item.entry)
    }
  }

  /**
   * 编译结束
   * @param {String} entry 入口信息
   * @param {String} str 打印的信息
   */
  function compileEnd(entry, str = '') {
    if (!compileRes[ entry ]) {
      return
    }
    finishLen++
    if (str) {
      compileRes[ entry ].log.unshift(str)
    }
    /* 如果key值数量达到入口数量，说明全部编译完成 */
    if (finishLen === entries.length) {
      /* 暂定动画 */
      spinner.stop()

      /* 打印log数据 */
      for (const key in compileRes) {
        const item = compileRes[ key ]

        item.log.forEach(log => console.log(log))
      }
    }
  }

  /**
   * 保存后重新编译成功，继续打印渎职
   */
  function saveLog(entry) {
    const item = compileRes[ entry ]

    item.log.forEach(log => console.log(log))
  }
}
